package com.tinyseed.emcp.api.productionRule.service.impl;

import com.tinyseed.emcp.api.basicdata.repository.WorkshopRepository;
import com.tinyseed.emcp.api.productionRule.bean.ReductionInputDTO;
import com.tinyseed.emcp.api.productionRule.bean.ReductionOutputDTO;
import com.tinyseed.emcp.api.productionRule.entity.Reduction;
import com.tinyseed.emcp.api.productionRule.repository.ReductionRepository;
import com.tinyseed.emcp.api.productionRule.service.ReductionService;
import com.tinyseed.emcp.api.productionRule.transfer.ReductionTransfer;
import com.tinyseed.hmxx.common.base.PageData;
import com.tinyseed.hmxx.common.utils.QueryHelp;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class ReductionServiceImpl implements ReductionService {

    private final ReductionRepository reductionRepository;

    public ReductionServiceImpl(ReductionRepository reductionRepository, WorkshopRepository workshopRepository) {
        this.reductionRepository = reductionRepository;
    }

    @Override
    public List<ReductionOutputDTO> getList() {
        Pageable pageable = PageRequest.of(0, 15);
        /*查找企业*/
        Page<Reduction> enterpriseList = reductionRepository.findAll(pageable);
        /*转换格式为outputdto*/
        List<ReductionOutputDTO> reductionOutputDTOList = new ArrayList<>();
        enterpriseList.getContent().forEach(temp -> {
            ReductionOutputDTO reductionOutputDTO1 = new ReductionOutputDTO();
            BeanUtils.copyProperties(temp, reductionOutputDTO1);
            reductionOutputDTOList.add(reductionOutputDTO1);
        });
        return reductionOutputDTOList;
    }

//    @Override
//    public List<ReductionOutputDTO> findReductionByPage(int current, int size) {
//        Page<Reduction> reductions = reductionRepository.findAll( PageRequest.of(current, size));
//        List<ReductionOutputDTO> reductionOutputDTOS = new ArrayList<>();
////        reductions.getContent().forEach(temp ->reductionOutputDTOS.add(temp.convertToReductionOutputDTO()));
//        return reductionOutputDTOS;
//    }

    @Override
    public Page getList(ReductionInputDTO inputDTO, int size, int current) {
        Pageable pageable = PageRequest.of(current - 1, size);
        return reductionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, inputDTO, criteriaBuilder), pageable);
    }

    @Override
    public ReductionOutputDTO save(ReductionInputDTO request) {

        Reduction reduction = reductionRepository.save(request.convertToReduction());
        ReductionOutputDTO reductionOutputDTO = new ReductionOutputDTO();
        BeanUtils.copyProperties(reduction, reductionOutputDTO);
        return reductionOutputDTO;
    }

    @Override
    public ReductionOutputDTO update(ReductionInputDTO request) {

        Reduction reduction = reductionRepository.save(request.convertToReduction());
        ReductionOutputDTO reductionOutputDTO = new ReductionOutputDTO();
        BeanUtils.copyProperties(reduction, reductionOutputDTO);
        return reductionOutputDTO;
    }

    @Override
    public ReductionOutputDTO getDataById(Long id) {
        Reduction reduction = reductionRepository.getOne(id);
        ReductionOutputDTO reductionOutputDTO = new ReductionOutputDTO();
        BeanUtils.copyProperties(reduction, reductionOutputDTO);
        return reductionOutputDTO;
    }

    @Override
    public void delete(Long id) {
        reductionRepository.deleteById(id);
    }

    @Override
    public PageData page(int size, int current, ReductionInputDTO reductionInputDTO) {
        Pageable pageable = PageRequest.of(current, size, Sort.Direction.DESC, "modifyTime");
        Page<Reduction> result = reductionRepository.findAll((Root<Reduction> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) -> {
            //必须用 List<Predicate>，否则不能多条件查询
            List<Predicate> list = new ArrayList<>();
            if (reductionInputDTO.getLevel() != null && !"".equals(reductionInputDTO.getLevel())) {
                Predicate p1 = criteriaBuilder.equal(root.get("level").as(Long.class), reductionInputDTO.getLevel());
                list.add(p1);
            }
            if (reductionInputDTO.getStartCreateTime() != null && !"".equals(reductionInputDTO.getStartCreateTime())) {
                Predicate p2 = criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(root.get("startTime").as(String.class), reductionInputDTO.getStartCreateTime()));
                list.add(p2);
            }
            if (reductionInputDTO.getEndCreateTime() != null && !"".equals(reductionInputDTO.getEndCreateTime())) {
                Predicate p3 = criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(root.get("endTime").as(String.class), reductionInputDTO.getEndCreateTime()));
                list.add(p3);
            }
            Predicate[] p = list.toArray(new Predicate[0]);
            return criteriaBuilder.and(p);
        }, pageable);
        List<ReductionOutputDTO> reductionOutputDTOList = new ArrayList<>();
        result.getContent().forEach(temp -> reductionOutputDTOList.add(ReductionTransfer.INSTANCE.mapModel2OutPut(temp)));
        PageData pageData = new PageData();
        pageData.setStart(result.getNumber());
        pageData.setData(reductionOutputDTOList);
        pageData.setTotal(result.getTotalElements());
        pageData.setLimit(result.getSize());
        return pageData;
    }
    @Transactional
    @Override
    public void deleteBatch(Long[] ids) {
        reductionRepository.deleteReductionsByIdIsIn(ids);
    }
    @Override

    public List<Reduction> getActiveList() {

        /*找到正在运行的规则*/
        return reductionRepository.getAllByActiveEquals(1L);

    }
}
